package sumline

import (
	"encoding/xml"
	"fmt"
)

// XMLResultType is the result type in XML format
type XMLResultType int8 // using int8 = XMLResultType

const (
	// xml result with langs is the result type for each language in xml format
	XMLResultWithLangs XMLResultType = iota
	// xml result with files is the result type for each file in xml format
	XMLResultWithFiles
)

// XML total Languages is the total result in xml format
type XMLTotalLanguages struct {
	SumFiles int32 `xml:"sum_files,attr"`
	Code     int32 `xml:"code,attr"`
	Comment  int32 `xml:"comment,attr"`
	Blank    int32 `xml:"blank,attr"`
}

// XMLResultLanguages stores the results in XML format
type XMLResultLanguages struct {
	Languages []SumLineLanguage `xml:"language"`
	Total     XMLTotalLanguages `xml:"total"`
}

// XMLTotalFiles is the total result per file in XML format
type XMLTotalFiles struct {
	Code    int32 `xml:"code,attr"`
	Comment int32 `xml:"comment,attr"`
	Blank   int32 `xml:"blank,attr"`
}

// XMLResultFiles stores per file results in XML format
type XMLResultFiles struct {
	Files []SumLineFile `xml:"file"`
	Total XMLTotalFiles `xml:"total"`
}

// XMLResult stores the result in xml format
type XMLResult struct {
	XMLName      xml.Name            `xml:"results"`
	XMLFiles     *XMLResultFiles     `xml:"files,omitempty"`
	XMLLanguages *XMLResultLanguages `xml:"languages,omitempty"`
}

// Encode outputs XMLResult in a human readable format
func (x *XMLResult) Encode() {
	// double space
	if output, err := xml.MarshalIndent(x, "", "  "); err == nil {
		fmt.Printf(xml.Header)
		fmt.Println(string(output))
	}
}

// NewXMLResultFrom sumline returns XML result with the default data set
func NewXMLResultFromSumLine(total *Language, sortedLangs Languages, _ XMLResultType) *XMLResult {
	var langs []SumLineLanguage
	for _, language := range sortedLangs {
		l := SumLineLanguage{
			Name:      language.Name,
			FileCount: int32(len(language.Files)),
			Code:      language.Code,
			Comments:  language.Comments,
			Blanks:    language.Blanks,
		}

		langs = append(langs, l)
	}

	tol := XMLTotalLanguages{
		Code:     total.Code,
		Comment:  total.Comments,
		Blank:    total.Blanks,
		SumFiles: total.Total,
	}

	target := &XMLResultLanguages{
		Languages: langs,
		Total:     tol,
	}

	return &XMLResult{
		XMLLanguages: target,
	}
}
